<?php
/*
 * Project:	WandChart, a diagram maker based on MagickWand
 * File:        wandchart.inc.php
 * Author:      MDZ <kingittiger@gmail.com>
 * Version:     1.0
 * Copyright:   2007 by MDZ
 * 
*/

require_once("languages.php");

class wandChart {

// Diagram types
var $diagTypeArray = array(
	"DEFAULT" => 1,
	"LINE" => 1,
	"BAR" => 2,
	"BOX" => 3,
	"STICK" => 4,
	"CHAR" => 5,
	"PIE" => 6
);

// Diagram Coordinates
var $diagCoordArray = array(
	"DEFAULT" => 1,
	"RIGHT" => 1,
	"LOG" => 2
);

// public configuration variables
var $images_dir          		= "images";
var $fonts_dir                     = "fonts";
var $logo                         = "logo.png";
var $canvas         			= "blank.png";
var $font                         = "msyh.ttf";
var $fontbd                   = "msyhbd.ttf";
var $lang	                     = "en";

// private internal variables
var $chart_obj             = null;
var $chart_coord            = 1;
var $output_type      = "png";
var $chart_title			= "A WandChart demo";
var $chart_info		= array("version" => "by WandChart 1.0  (C) 2007");
var $chart_size  = array("width" => 610, "height" => 300);
var $colors     = array("frame" => "#555555", "mesh" => "#cccccc");
var $padding		= array("top" => 22, "right" => 22, "bottom" => 31, "left" => 25);
var $limits		= array("x_min" => 0, "x_max" => 0, "y_min" => 0, "y_max" => 0);
var $effective_size  = array("top" => null, "right" => null, "bottom" => null, "left" => null);
var $label		= array("x" => "Axes x", "y" => "Axes y");
var $font_size  = array("normal" => 10, "small" => 9, "title" => 12);
var $datas		= array();


// Functions
      
function wandChart() {
	$this->chart_obj = NewMagickWand();
	$this->reCalcEffectiveSize();
}

# 准备画布
function prepareCanvas() {
	$img_dir = $this->delLastSlash($this->images_dir);
	$canvas_img = $img_dir . "/" . $this->canvas;
	MagickReadImage($this->chart_obj, $canvas_img);
	MagickScaleImage($this->chart_obj, $this->chart_size["width"], $this->chart_size["height"]);
}

# 去掉字符串后多余的符号 "/"
function delLastSlash($str) {
	while (ereg("\/$", $str)) {
		$str = substr($str, 0, strlen($str) - 1);
	}
	return $str;
}

# 设置 x 轴和 y 轴的标签
function setLabel($x_label, $y_label) {
	$this->label["x"] = $x_label;
	$this->label["y"] = $y_label;
}

# 设置图题头
function setTitle($title_str) {
	$this->chart_title = $title_str;
}

# 设置坐标系类型
function setCoord($coord) {
	$this->chart_coord = (! $this->diagCoordArray[$coord]) ? $this->diagCoordArray["DEFAULT"] : $this->diagCoordArray[$coord];
}

# 设置输出图像的文件类型
function setOutputType($op_type) {
	$alow_type = array("png", "jpg", "jpeg", "gif", "bmp");
	if (false === array_search(strtolower($op_type), $alow_type)) {
		$this->output_type = $alow_type[0];
	} else {
		$this->output_type = $op_type;
	}
}

# 设置视界与图像边距
function setPadding($top=0, $right=0, $bottom=0, $left=0) {
	$this->padding["top"] = $top;
	$this->padding["right"] = $right;
	$this->padding["bottom"] = $bottom;
	$this->padding["left"] = $left;
}

# 设置元素颜色
function setColors($frame, $mesh) {
	$this->colors["frame"] = $frame;
	$this->colors["mesh"] = $mesh;
}

# 绘制标题
function drawTitle() {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->colors["frame"]);
	$fnt_dir = $this->delLastSlash($this->fonts_dir);
	DrawSetFillColor($drawer_obj, $pixel_obj);
	DrawSetFont($drawer_obj, $fnt_dir . "/" . $this->fontbd);
	DrawSetFontSize($drawer_obj, $this->font_size["title"]);
	DrawSetGravity($drawer_obj, MW_NorthGravity);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, 0, 0, 0, $this->chart_title);
}

function drawFooter() {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->colors["frame"]);
	$fnt_dir = $this->delLastSlash($this->fonts_dir);
	DrawSetFillColor($drawer_obj, $pixel_obj);
	DrawSetFont($drawer_obj, $fnt_dir . "/" . $this->font);
	DrawSetFontSize($drawer_obj, $this->font_size["small"]);
	DrawSetGravity($drawer_obj, MW_SouthWestGravity);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, 0, 0, 0, $this->chart_info["version"]);
}

# 绘制框架
function drawFrameMesh() {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->colors["frame"]);
	$fnt_dir = $this->delLastSlash($this->fonts_dir);
	$font = $fnt_dir . "/" . $this->font;
	DrawSetFillColor($drawer_obj, $pixel_obj);
	DrawSetFont($drawer_obj, $font);
	DrawSetFontSize($drawer_obj, $this->font_size["normal"]);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, $this->effective_size["left"], $this->effective_size["bottom"] + 12, 0, $this->limits["x_min"]);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, $this->effective_size["right"] - 5, $this->effective_size["bottom"] + 12, 0, $this->limits["x_max"]);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, $this->effective_size["left"] - 20, $this->effective_size["bottom"], 0, $this->limits["y_min"]);
	MagickAnnotateImage($this->chart_obj, $drawer_obj, $this->effective_size["left"] - 20, $this->effective_size["top"], 0, $this->limits["y_max"]);
		
	DrawSetStrokeColor($drawer_obj, $pixel_obj);
	DrawSetFillAlpha($drawer_obj, 0);
	DrawRectangle($drawer_obj, $this->effective_size["left"], $this->effective_size["top"], $this->effective_size["right"], $this->effective_size["bottom"]);
	MagickDrawImage($this->chart_obj, $drawer_obj);
    	
	$pixel_words_obj = NewPixelWand($this->colors["frame"]);
	$drawer_words_obj = NewDrawingWand();
	DrawSetFillColor($drawer_words_obj, $pixel_words_obj);
	DrawSetFont($drawer_words_obj, $font);
	DrawSetFontSize($drawer_words_obj, $this->font_size["normal"]);
	DrawSetGravity($drawer_words_obj, MW_SouthGravity);
	MagickAnnotateImage($this->chart_obj, $drawer_words_obj, 0, 12, 0, $this->label["x"]);
	DrawSetGravity($drawer_words_obj, MW_WestGravity);
	MagickAnnotateImage($this->chart_obj, $drawer_words_obj, 12, 0, -90, $this->label["y"]);
}

# 设置画布大小
function setSize($width, $height) {
	if ($width < 200) { $width = 200; }
	if ($height < 150) { $height = 150;}
	$this->chart_size["width"] = $width;
	$this->chart_size["height"] = $height;
	$this->reCalcEffectiveSize();
}
	
# 重新计算可绘制的区域大小
function reCalcEffectiveSize() {
	$this->effective_size["top"] = $this->padding["top"];
	$this->effective_size["left"] = $this->padding["left"];
	$this->effective_size["right"] = $this->chart_size["width"] - $this->padding["right"];
	$this->effective_size["bottom"] = $this->chart_size["height"] - $this->padding["bottom"];
}

# 获取图表类型的数值
function getTypeNum($type) {
	$type_num = $this->diagTypeArray[$type];
	return (! $type_num) ? 1 : $type_num;
}

# 绘制图表
function plot($x, $y, $type="DEFAULT", $color="blue") {
	$type_name = explode("|", $type);
	$type_num = $this->getTypeNum($type_name[0]);
	$suffix = count($this->datas);
	$this->datas[$suffix] = array();
	$this->datas[$suffix]["type"] = $type_num;
	$this->datas[$suffix]["color"] = $color;
	if ($type_num == $this->getTypeNum("CHAR")) { $this->datas[$suffix]["char"] = $type_name[1]; }
	$this->analyzeData($x, $y, $suffix);
}
	
# 分析数据
function analyzeData($x, $y, $suffix) {
	global $errors;
	if (count($x) != count($y)) {
		$this->error(1);
		return false;
	}
	$this->datas[$suffix]["x"] = $x;
	$this->datas[$suffix]["y"] = $y;
	$this->getLimits($x, $y, $suffix);
	// $this->coordTransmation($x, $y, $suffix);
	return true;
}
	
# 生成 x 数据数组
function makeX($str) {
	$str_array = explode(":", $str);
	$i = 0;
	if (($str_array[1] > 0 && $str_array[0] > $str_array[2]) || ($str_array[1] < 0 && $str_array[0] < $str_array[2])) { $this->error(2); return false; }
	if ($str_array[1] > 0) {
		for ($j = $str_array[0]; $j <= $str_array[2]; $j += $str_array[1] ) {
			if (abs($j) < 1E-15) { $j = 0; }
			$x[$i] = $j;
			$i ++;
		}
		if ($j > $str_array[2] && ($j - $str_array[1]) < $str_array[2]) { $x[$i] = $str_array[2]; }
	} else {
		for ($j = $str_array[0]; $j >= $str_array[2]; $j += $str_array[1]) {
			if (abs($j) < 1E-15) { $j = 0; }
			$x[$i] = $j;
			$i ++;
		}
		if ($j < $str_array[2] && ($j - $str_array[1]) > $str_array[2]) { $x[$i] = $str_array[2]; }
	}
	return $x;
}
	
# 生成 y 数据数组
function makeY($fun_str, $x) {
	foreach ($x as $key => $value) {
		$function_str = ereg_replace("<x>", $value . "", $fun_str);
		eval("\$temp = " . $function_str . " ;");
		$y[$key] = $temp;
	}
	return $y;
}
	
# 坐标轴变换，将数据数组转化到图上的坐标轴
function coordTransmation() {
	$x_coord = abs($this->chart_size["width"] - $this->padding["right"] - $this->padding["left"]);
	$x_data = abs($this->limits["x_max"] - $this->limits["x_min"]);
	$y_coord = abs($this->chart_size["height"] - $this->padding["bottom"] - $this->padding["top"]);
	$y_data = abs($this->limits["y_max"] - $this->limits["y_min"]);
	foreach ($this->datas as $key => $value) {
		$this->datas[$key]["diag_x"] = array();
		$this->datas[$key]["diag_y"] = array();
		foreach ($this->datas[$key]["x"] as $k => $v) {
			$a = $v - $this->limits["x_min"];
			$this->datas[$key]["diag_x"][$k] = $a * $x_coord / $x_data + $this->padding["left"];
		}
		foreach ($this->datas[$key]["y"] as $k => $v) {
			$a = $v - $this->limits["y_min"];
			$this->datas[$key]["diag_y"][$k] = $this->effective_size["bottom"] - ($a * $y_coord / $y_data);
		}
	}
}
	
# 获取数据上下限
function getLimits($x, $y, $suffix) {
	$x_max = max($x);
	$x_min = min($x);
	$y_max = max($y);
	$y_min = min($y);
	$this->limits["x_min"] = ($suffix == 0) ? $x_min : min($this->limits["x_min"], $x_min);
	$this->limits["x_max"] = ($suffix == 0) ? $x_max : max($this->limits["x_max"], $x_max);
	$this->limits["y_min"] = ($suffix == 0) ? $this->getLowerLimit($y_min) : min($this->limits["y_min"], $this->getLowerLimit($y_min));
	$this->limits["y_max"] = ($suffix == 0) ? $this->getUpperLimit($y_max) : max($this->limits["y_max"], $this->getUpperLimit($y_max));
}
	
// function getDigit() : 获取数值位数
// $num > 1：返回正整数
// $num < 1：返回负整数
// $num = 0：返回 0
function getDigit($num) {
	$abs_num = abs($num);
	$flag = 0;
	if ($abs_num >= 1) {
		while(floor($abs_num) != 0) {
			$abs_num /= 10;
			$flag += 1;
		}
	} else {
		if ($abs_num != 0) {
			while(floor($abs_num) == 0) {
				$abs_num *= 10;
				$flag -= 1;
			}
		}
	}
	return $flag;
}

### 获取数值在坐标中的上限
function getUpperLimit($num) {
	$flag = ($num >= 0) ? 1 : -1;
	$num = abs($num);
	$num_10_pm1 = pow(10, $this->getDigit($num) - 1);
	$num_10_pm2 = pow(10, $this->getDigit($num) - 2);
	$num_10_pp1 = pow(10, -($this->getDigit($num)));
	$num_10_pp2 = pow(10, -($this->getDigit($num)) + 1);

	$upperlimit = $num;
	if ($num == 0) {
		$upperlimit = 0;
	} else {
		if ($flag > 0) {              # 数值为正
			if ($num >= 1) {
				$num_t1 = $num / $num_10_pm2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$upperlimit = ceil($flag * $num / $num_10_pm1) * $num_10_pm1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$upperlimit = (floor($flag * $num / $num_10_pm1) + 0.5) * $num_10_pm1;
				}
			} elseif ($num < 1 && $num > 0) {
				$num_t1 = $num * $num_10_pp2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$upperlimit = ceil($flag * $num * $num_10_pp1) / $num_10_pp1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$upperlimit = (floor($flag * $num * $num_10_pp1) + 0.5) / $num_10_pp1;
				}
			}
		} else {              # 数值为负
			if ($num >= 1) {
				$num_t1 = $num / $num_10_pm2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$upperlimit = (floor($flag * $num / $num_10_pm1) + 0.5) * $num_10_pm1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$upperlimit = ceil($flag * $num / $num_10_pm1) * $num_10_pm1;
				} else {
					$upperlimit = $flag * $num;
				}
			} elseif ($num < 1 && $num > 0) {
				$num_t1 = $num * $num_10_pp2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$upperlimit = (floor($flag * $num * $num_10_pp1) + 0.5) / $num_10_pp1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$upperlimit = ceil($flag * $num * $num_10_pp1) / $num_10_pp1;
				} else {
					$upperlimit = $flag * $num;
				}
			}
		}
	}
	return $upperlimit;
}

### 获取数值在坐标中的下限
function getLowerLimit($num) {
	$flag = ($num >= 0) ? 1 : -1;
	$num = abs($num);
	$num_10_pm1 = pow(10, $this->getDigit($num) - 1);
	$num_10_pm2 = pow(10, $this->getDigit($num) - 2);
	$num_10_pp1 = pow(10, -($this->getDigit($num)));
	$num_10_pp2 = pow(10, -($this->getDigit($num)) + 1);

	$lowerlimit = $num;
	if ($num == 0) {
		$lowerlimit = 0;
	} else {
		if ($flag > 0) {              # 数值为正
			if ($num >= 1) {
				$num_t1 = $num / $num_10_pm2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$lowerlimit = (floor($flag * $num / $num_10_pm1) + 0.5) * $num_10_pm1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$lowerlimit = floor($flag * $num / $num_10_pm1) * $num_10_pm1;
				}
			} elseif ($num < 1 && $num > 0) {
				$num_t1 = $num * $num_10_pp2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$lowerlimit = (floor($flag * $num * $num_10_pp1) + 0.5) / $num_10_pp1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$lowerlimit = floor($flag * $num * $num_10_pp1) / $num_10_pp1;
				}
			}
		} else {              # 数值为负
			if ($num >= 1) {
				$num_t1 = $num / $num_10_pm2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$lowerlimit = floor($flag * $num / $num_10_pm1) * $num_10_pm1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$lowerlimit = (floor($flag * $num / $num_10_pm1) + 0.5) * $num_10_pm1;
				} else {
					$lowerlimit = $flag * $num;
				}
			} elseif ($num < 1 && $num > 0) {
				$num_t1 = $num * $num_10_pp2;
				$num_t2 = $num_t1 % 10;
				if ($num_t2 >= 5) {
					$lowerlimit = floor($flag * $num * $num_10_pp1) / $num_10_pp1;
				} elseif ($num_t2 < 5 && $num_t2 > 0) {
					$lowerlimit = (floor($flag * $num * $num_10_pp1) + 0.5) / $num_10_pp1;
				} else {
					$lowerlimit = $flag * $num;
				}
			}
		}
	}
	return $lowerlimit;
}

# 绘制折线
function plotLine($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->datas[$suffix]["color"]);
	DrawSetStrokeColor($drawer_obj, $pixel_obj);
	$num = count($this->datas[$suffix]["diag_x"]);
	$flag = 0;
	$last_pair = array("x" => 0, "y" => 0);
	foreach ($this->datas[$suffix]["diag_x"] as $key => $value) {
		if ($flag == 0) {
			$last_pair["x"] = $value;
			$last_pair["y"] = $this->datas[$suffix]["diag_y"][$key];
			$flag = 1;
			continue;
		}
		DrawLine($drawer_obj, $last_pair["x"], $last_pair["y"], $value, $this->datas[$suffix]["diag_y"][$key]);
		$last_pair["x"] = $value;
		$last_pair["y"] = $this->datas[$suffix]["diag_y"][$key];
	}
    MagickDrawImage($this->chart_obj, $drawer_obj);
}

# 绘制柱状图
function plotBar($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->datas[$suffix]["color"]);
	DrawSetFillColor($drawer_obj, $pixel_obj);
	$num = count($this->datas[$suffix]["diag_x"]);
	$effective_width = $this->effective_size["right"] - $this->effective_size["left"];
	$width = $effective_width / (2 * $num) / 2;
	foreach ($this->datas[$suffix]["diag_x"] as $key => $value) {
		DrawRectangle($drawer_obj, $this->datas[$suffix]["diag_x"][$key] - $width, $this->datas[$suffix]["diag_y"][$key], $this->datas[$suffix]["diag_x"][$key] + $width, $this->effective_size["bottom"]);
	}
	MagickDrawImage($this->chart_obj, $drawer_obj);
}
	
# 绘制空心图
function plotBox($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->datas[$suffix]["color"]);
	DrawSetStrokeColor($drawer_obj, $pixel_obj);
	DrawSetFillAlpha($drawer_obj, 0);
	$num = count($this->datas[$suffix]["diag_x"]);
	$effective_width = $this->effective_size["right"] - $this->effective_size["left"];
	$width = $effective_width / (2 * $num) / 2;
	foreach ($this->datas[$suffix]["diag_x"] as $key => $value) {
		DrawRectangle($drawer_obj, $this->datas[$suffix]["diag_x"][$key] - $width, $this->datas[$suffix]["diag_y"][$key], $this->datas[$suffix]["diag_x"][$key] + $width, $this->effective_size["bottom"]);
	}
	MagickDrawImage($this->chart_obj, $drawer_obj);
}

# 绘制火柴棍图
function plotStick($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->datas[$suffix]["color"]);
	DrawSetStrokeColor($drawer_obj, $pixel_obj);
	DrawSetFillAlpha($drawer_obj, 0);
	$num = count($this->datas[$suffix]["diag_x"]);
	$radius = 2;
	foreach ($this->datas[$suffix]["diag_x"] as $key => $value) {
		DrawCircle($drawer_obj, $this->datas[$suffix]["diag_x"][$key], $this->datas[$suffix]["diag_y"][$key], $this->datas[$suffix]["diag_x"][$key], $this->datas[$suffix]["diag_y"][$key] + $radius);
		DrawLine($drawer_obj, $this->datas[$suffix]["diag_x"][$key], $this->datas[$suffix]["diag_y"][$key] + $radius, $this->datas[$suffix]["diag_x"][$key], $this->effective_size["bottom"]);
		// DrawRectangle($drawer_obj, $this->datas[$suffix]["diag_x"][$key] - $width, $this->datas[$suffix]["diag_y"][$key], $this->datas[$suffix]["diag_x"][$key] + $width, $this->effective_size["bottom"]);
	}
	MagickDrawImage($this->chart_obj, $drawer_obj);
}
    
# 绘制字符图
function plotChar($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand($this->datas[$suffix]["color"]);
	$fnt_dir = $this->delLastSlash($this->fonts_dir);
	$font = $fnt_dir . "/" . $this->font;
	DrawSetFillColor($drawer_obj, $pixel_obj);
	DrawSetFont($drawer_obj, $font);
	DrawSetFontSize($drawer_obj, $this->font_size["normal"]);
	foreach ($this->datas[$suffix]["diag_x"] as $key => $value) {
		MagickAnnotateImage($this->chart_obj, $drawer_obj, $this->datas[$suffix]["diag_x"][$key], $this->datas[$suffix]["diag_y"][$key], 0, $this->datas[$suffix]["char"]);
	}
	MagickDrawImage($this->chart_obj, $drawer_obj);
}
    
# 绘制饼图
function plotPie($suffix) {
	$drawer_obj = NewDrawingWand();
	$pixel_obj = NewPixelWand("black");
	DrawSetFillColor($drawer_obj, $pixel_obj);
	$start_degree = 0;
	$height = $this->chart_size["height"];
	$width = $this->chart_size["width"];
	$ox = $width / 4;
	$oy = $height / 2;
	$radius = 2 * min($ox, $oy) / 3;
	$total = 0;
	foreach ($this->datas[$suffix]["y"] as $value) {
		$total += $value;
	}
	$suffix_180 = -1;
	foreach ($this->datas[$suffix]["y"] as $key => $value) {
		$percent = $value / $total;
		$degree = $percent * 360;
		$end_degree = $start_degree + $degree;
		if ($degree > 180) {
			$suffix_180 = $key;
			PixelSetColor($pixel_obj, $this->getColor());
			DrawSetFillColor($drawer_obj, $pixel_obj);
			DrawEllipse($drawer_obj, $ox, $oy, $radius, $radius, $start_degree, $end_degree);
			break;
		}
		$start_degree = $end_degree;
	}
	$start_degree = 0;
	foreach ($this->datas[$suffix]["y"] as $key => $value) {
		PixelSetColor($pixel_obj, $this->getColor());
		DrawSetFillColor($drawer_obj, $pixel_obj);
		$percent = $value / $total;
		$degree = $percent * 360;
		$end_degree = $start_degree + $degree;
		if ($key != $suffix_180) {
			DrawEllipse($drawer_obj, $ox, $oy, $radius, $radius, $start_degree, $end_degree);
			$polygon = $this->getPolygon($ox, $oy, $radius, $start_degree, $end_degree);
			DrawPolygon($drawer_obj, $polygon);
		}
		$start_degree = $end_degree;
	}
	MagickDrawImage($this->chart_obj, $drawer_obj);
}
    
# 获得扇形三角区多边形数组
function getPolygon($ox, $oy, $radius, $start_degree, $end_degree) {
	$polygon = array();
	$polygon[] = $ox;
	$polygon[] = $oy;
	$polygon[] = $ox + $radius * cos(deg2rad($start_degree));
	$polygon[] = $oy + $radius * sin(deg2rad($start_degree));
	$polygon[] = $ox + $radius * cos(deg2rad($end_degree));
	$polygon[] = $oy + $radius * sin(deg2rad($end_degree));
	return $polygon;
}
    
# 获取十六进制随机颜色
function getColor() {
	return "#" . dechex(mt_rand(0, 16777215));
}
    
# 通过 $this->datas 绘制图像
function drawDatas($just_one, $suffix) {
	if (! $just_one) {
		foreach ($this->datas as $key => $value) {
			switch ($this->datas[$key]["type"]) {
				case 1:
					$this->plotLine($key);
					break;
				case 2:
					$this->plotBar($key);
					break;
				case 3:
					$this->plotBox($key);
					break;
				case 4:
					$this->plotStick($key);
					break;
				case 5:
					$this->plotChar($key);
					break;
				case 6:
					$this->plotPie($key);
					break;
				default:
					$this->plotLine($key);
			}
		}
	} else {
		switch ($this->datas[$suffix]["type"]) {
			case 6:
				$this->plotPie($suffix);
				break;
			default:
				$this->plotLine($suffix);
		}
	}
}

# 输出图像
function outputChart() {
	global $errors;
	$just_one = false;
	$suffix = null;
	$this->coordTransmation();
	foreach ($this->datas as $key => $value) {
		if ($this->datas[$key]["type"] == $this->getTypeNum("PIE")) {
			$just_one = true;
			$suffix = $key;
			break;
		}
	}
	if (! $just_one) {
		$this->drawFrameMesh();
	}
	$this->drawTitle();
	$this->drawFooter();
	$this->drawDatas($just_one, $suffix);
	header("Content-Type: image/" . $this->output_type);
	if (! MagickEchoImageBlob($this->chart_obj)) {
		$this->error(0);
	}
}

function error($error_id) {
	global $errors;
	echo $errors[$this->lang][$error_id];
}

}

?>
